﻿using System.Collections.Generic;
using Api.Model;
using Core.Infrastructure.AnimationService;
using Core.Infrastructure.Constants;
using Core.Infrastructure.ErrorReportService;
using Core.Infrastructure.EventArgs;
using Core.Infrastructure.ScreenManager;
using Core.Infrastructure.Settings;
using Core.Infrastructure.ViewModelBase;
using Core.ProxyService;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.Unity;
using System;
using System.Linq;
using Core.Model;

namespace Core.ScreenStore.ViewModel
{
    public class ArticlesViewModel : ViewModelBase, INavigable, INavigable<Tag>
    {
        private ICoreProxyService service;
        private IErrorReportService errorReportService;
        private IArticlesModel articlesModel;
        private bool isBusy;
        private IEnumerable<Article> articles;
        private IEnumerable<Tag> tags;
        public override bool IsActive { get; set; }

        public bool IsBusy
        {
            get 
            { 
                return isBusy;
            }
            set 
            {
                isBusy = value;
				base.RaisePropertyChanged(() => IsBusy);
            }
        }
        
        public IEnumerable<Article> Articles
        {
            get
            {
                return articles;
            }
            set
            {
                articles = value;
                base.RaisePropertyChanged(() => this.Articles);
            }
        }

        public IEnumerable<Tag> Tags
        {
            get
            {
                return tags;
            }
            set
            {
                tags = value;
                base.RaisePropertyChanged(() => this.Tags);
            }
        }

        public DelegateCommand<Article> SelectArticleCommand { get; private set; }
        public DelegateCommand<Tag> SelectTagCommand { get; private set; }

        public ArticlesViewModel(IEventAggregator eventAggregator,
                                IAnimationService animationService,
                                IUnityContainer container,
                                ISettings settings,
                                ICoreProxyService service,
                                IErrorReportService errorReportService,
                                IArticlesModel articlesModel)
            : base(eventAggregator, animationService, container, settings)
        {
            AnimationService = animationService;
            Settings = settings;
            Loaded = new DelegateCommand<object>(OnLoad);
            Unloaded = new DelegateCommand<object>(OnUnload);
            this.service = service;
            this.errorReportService = errorReportService;
            this.articlesModel = articlesModel;
            SelectArticleCommand = new DelegateCommand<Article>(article => SelectArticle(article),
                                                                  article => CanSelectArticle(article));

            SelectTagCommand = new DelegateCommand<Tag>(tag => SelectTag(tag));
        }

        public void SelectArticle(Article article)
        {
            var screenEventArgs = new ScreenEventArgs
            {
                ScreenType = ScreenType.ArticleDetailsScreen,
                RegionName = RegionConstants.RegionMainArea,
                PerformAnimation = true,
                NavigationArgs = article,
            };
            this.EventAggregator.GetEvent<ScreenActivateEvent>().Publish(screenEventArgs);
        }

        public void SelectTag(Tag tag)
        {
            var screenEventArgs = new ScreenEventArgs
            {
                ScreenType = ScreenType.ArticlesScreen,
                RegionName = RegionConstants.RegionMainArea,
                PerformAnimation = true,
                NavigationArgs = tag,
            };
            this.EventAggregator.GetEvent<ScreenActivateEvent>().Publish(screenEventArgs);
        }

        public bool CanSelectArticle(Article article)
        {
            return !IsBusy;
        }
        public override void OnUnload(object obj)
        {
            this.IsActive = false;
        }

        public override void OnLoad(object obj)
        {
            this.IsActive = true;         
        }

        public void LoadArticles()
        {
            IsBusy = true;
            service.GetArticlesAsync(args =>
            {
                IsBusy = false;

                if (args.Error == null && !args.Cancelled)
                {
                    Articles = args.Result;
                    articlesModel.AddArticles(args.Result);

                    if (articlesModel.AreTagsAvailable)
                    {
                        var tags = articlesModel.GetTags();
                        this.Tags = tags;
                        EventAggregator.GetEvent<TagsLoadedEvent>().Publish(tags);
                    }
                }
                else
                {
                    errorReportService.Report("Cannot load articles");
                }
            });
        }

        public void OnNavigate()
        {
            if (!articlesModel.AreArticlesLoaded)
            {
                LoadArticles();
            }
            else
            {
                this.Articles = articlesModel.GetArticles();
            }          
        }

        public void OnNavigate(Tag args)
        {
            this.Articles = this.articlesModel.GetArticles().Where(article => article.Tags.Contains(args));
        }
    }
}
